/*	TMModelKeyFromViewNameTransformer.h
 *
 * Copyright (c)2005 Tim Morgan. All rights reserved. Please visit
 * http://tmorgan.shutupgeorge.com/other/license.html for more information about
 * your rights and responsibilities regarding this source code.
 */

#pragma once

#import <Cocoa/Cocoa.h>

/**
 * Associates key constants (as used in the program) with control names (as used
 * in the user interface). Thus, a control allowing the user to select from
 * multiple options can have human-readable names that get translated into
 * program-useable constants by subclasses of this class.
 *
 * The programmer need only make calls to
 * {@link TMModelKeyFromViewNameTransformer#associateViewName:withModelKey:}
 * for each key to be associated with a view name. For example, if the view has
 * a pop-up menu titled "Background Color" with options "Red", "Green", and
 * "Blue", the program might have string constants to represent these choices
 * with values "MyBackgroundColorRed", "MyBackgroundColorGreen",
 * and "MyBackgroundColorBlue". This class would handle the conversion if the
 * view uses Cocoa bindings, so that the model stores the choice as a unique key
 * and the view displays the choice as a human-readable string.
 *
 * As a different example, if a text field can display one of two values
 * depending on a Boolean value in the model (wrapped as a <code>NSNumber</code>
 * class), the two Boolean values could be associated with the two possible
 * text strings using this class.
 *
 * Because the transformation is two-way, model keys and view names must have a
 * one-to-one association. Each model key must resolve to exactly one view name,
 * and each view name must be referenced by exactly one model key. Operation is
 * undefined if this requirement is not followed.
 *
 * View names must be <code>NSString</code>s. Model keys can either be
 * <code>NSString</code>s or <code>NSNumber</code>s. In the latter case, the
 * <code>NSNumber</code> is converted to an <code>NSString</code> using its
 * <code>stringValue</code> method for internal storage. Thus, comparison of
 * two <code>NSNumber</code> keys is done by converting them to strings and
 * comparing the strings. To conform with Cocoa bindings, an
 * <code>NSString</code> is always returned, even if the model key was
 * originally an <code>NSNumber</code>.
 *
 * There is a great deal of confusion in the use of the terms <i>key</i>,
 * <i>value</i>, and <i>name</i> within the code and comments. Please carefully
 * consider which meaning of the term is intended with each occurence. A
 * <i>model key</i> is an object that has programmatic meaning, and represents a
 * setting in a code-manipulatable way. A <i>view name</i> is the corresponding
 * human-readable string to the model key, and is suitable for display in the
 * UI. A <i>hash key</i> and a <i>hash value</i> are self-explanatory to anyone
 * with a knowledge of hash tables. Confusion arises because model keys are
 * hashed as keys in one map and values in the other, and likewise, view names
 * are hashed as values in one map and keys in the other. So when you see the
 * word <i>key</i>, think carefully to determine if it means model key, hash key,
 * or possibly both. The words <i>value</i> and <i>name</i> do not have this
 * ambiguity.
 *
 * @author Tim Morgan
 */

@interface TMModelKeyFromViewNameTransformer : NSValueTransformer {
	@private NSMutableDictionary	*namesForKeys, *keysForNames;
}

#pragma mark <<initialization/deallocation>>

/**
 * Initializes a transformer instance. No model key to view name mappings will
 * be specified; you must do so manually with
 * {@link TMModelKeyFromViewNameTransformer#associateViewName:withModelKey:}.
 *
 * @return The initialized instance
 */

- (id) init;

/**
 * Initializes a transformer instance with the mapping specified in the given
 * property list file. The property list file should contain a single dictionary
 * where model <i>keys</i> are the dictionary <i>values</i> and view
 * <i>names</i> are the dictionary <i>keys</i>. The mapping specified in the
 * plist file will be used for this instance. Raises an exception if an error
 * occurs locating or parsing the file.
 *
 * @param plistFile path to the property list file
 * @return The initialized instance
 */

- (id) initWithMappingPlist:(NSString *)plistFile;

/**
 * Deallocates local memory usage.
 */

- (void) dealloc;

#pragma mark <<association>>

/**
 * Associates a title/value used by a control in the view with a string constant
 * used in the program. This method should be called for each key and view name
 * in a set of options. Does nothing if either parameter is null.
 *
 * @param name the name used in the view
 * @param key the string constant used in the program
 */

- (void) associateViewName:(id)name withModelKey:(id)key;

/**
 * Returns an enumerator over all view names associated in this instance.
 *
 * @return An enumerator over view names
 */

- (NSEnumerator *) viewNames;

/**
 * Returns an enumerator over all model keys associated in this instance.
 *
 * @return An enumerator over model keys
 */

- (NSEnumerator *) modelKeys;

@end